package com.px.framework.interceptor.mybatis;

import com.px.common.core.domain.entity.SysDept;
import com.px.common.core.domain.model.LoginUser;
import com.px.common.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;

@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class MybatisInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        LoginUser loginUser = null;
        try {
            loginUser = SecurityUtils.getLoginUser();
        } catch (Exception e) {
            return invocation.proceed();
        }

        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameter = invocation.getArgs()[1];

        // 如果是在新增部门,则不填充基础信息
      if (parameter instanceof SysDept) {
            return invocation.proceed();
        }
        // 填充基础信息
        Map<String, Object> comFileds = new HashMap<>();
        if (mappedStatement.getSqlCommandType() == SqlCommandType.INSERT) {
            comFileds.put("createBy", loginUser.getUserId() + "");
            comFileds.put("createTime", new Date());
            comFileds.put("deptId", loginUser.getDeptId());
        }
        if (mappedStatement.getSqlCommandType() == SqlCommandType.UPDATE) {
            comFileds.put("updateBy", loginUser.getUserId() + "");
            comFileds.put("updateTime", new Date());
        }

        // 如果字段未设值,则使用填充值
        PropertyDescriptor[] ps = Introspector.getBeanInfo(parameter.getClass()).getPropertyDescriptors();
        for (PropertyDescriptor properdesc : ps) {
            if (StringUtils.isNotEmpty(properdesc.getName()) &&
                    comFileds.get(properdesc.getName()) != null) {
                Class<?> propertyType = properdesc.getPropertyType();
                System.out.println(propertyType.getName());
                Method getter = properdesc.getReadMethod();

                if (getter == null) {
                    continue;
                }
                getter.setAccessible(true);
                Object obj = getter.invoke(parameter);
                if (obj != null && StringUtils.isNotEmpty(Objects.toString(obj, ""))) {
                    continue;
                }

                Method setter = properdesc.getWriteMethod();
                if (setter == null) {
                    continue;
                }
                setter.setAccessible(true);
                setter.invoke(parameter, comFileds.get(properdesc.getName()));
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Interceptor.super.plugin(target);
    }

    @Override
    public void setProperties(Properties properties) {
        Interceptor.super.setProperties(properties);
    }
}
